package com.anlu.base.jdk.jdk8;

import com.alibaba.fastjson2.JSON;
import com.anlu.base.model.User;
import com.anlu.base.model.function.TriFunction;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.event.WindowFocusListener;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.*;

public class FunTest1 {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Test
    void test1(){
        Supplier<String>  getString = () -> "hello world";
        System.out.println(getString.get());
    }

    @Test
    void test2(){
        BiFunction<Integer,Integer,Integer> add = (a,b) -> a+b;
        Integer sum = add.apply(1,2);
        logger.info("sum={}",sum);
    }
    @Test
    void test3(){

        TriFunction<Integer,Integer,Integer,Integer> add = (a,b,c) -> a+b+c;
        Integer sum = add.apply(1,2,3);
        logger.info("sum={}",sum);
    }

    @Test
    void test4(){

        User user = new User();
        user.setId(1);
        user.setAge(10);
        user.setName("安悦心");
        user.setBeginTime(new Date());

        var value = add(user,2,3,(a,b,c)-> {
                  user.setAge(b+c);
                  return user;
                },
                result->{
                    logger.info("user = {}", JSON.toJSONString(result));
                });
        logger.info("value = {}", JSON.toJSONString(value));
    }

    @Test
    void test5(){

        String s = "sdsdf";
        boolean b = checkString(s, s1 -> s1.contains("s"));
        logger.info("b = {}",b);

        boolean b1 = checkString(s, s1 -> s1.length() > 3);
        logger.info("b1 = {}",b1);
    }

    @Test
    void test6(){
        String s = "1s23123";
        boolean b = checkString(s, s1 -> s1.contains("s"), s1 -> s1.length() > 3);
        logger.info("b = {}",b);
    }

    @Test
    void test7(){
        String s= "1234";
        int res = change(s, s1 -> Integer.parseInt(s1));
        logger.info("res = {}",res);
    }

    @Test
    void test8(){
        String s = "12";
        change(s, s1 -> Integer.parseInt(s1)+10, s1 -> s1+"1");
    }

    @Test
    void test9(){
        List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("张三丰");
        list.add("张无忌");
        //要求：先对list集合中的元素进行过滤，找出姓张的人，
        //然后对新得到的姓张的集合中的元素进行过滤，找出姓名长度为3的人
        //最后遍历最终的集合
        list.stream().filter(name->name.startsWith("张"))
                .filter(name->name.length()>2)
                .forEach(name-> System.out.println(name));//注意forEach也是函数式接口

    }



    /*定义一个方法：
     *       参数传递一个String类型的字符串，传递一个predicate接口，泛型使用String
     *       使用predicate中的方法test对字符串进行判断，并把判断的结果返回*/
    public static Boolean checkString(String s, Predicate<String> pre){
        return pre.test(s);
    }

    public static Boolean checkString(String s, Predicate<String> pre,Predicate<String> pre2){
        return pre.and(pre2).test(s);
    }

    public static Boolean checkString2(String s, Predicate<String> pre,Predicate<String> pre2){
        return pre.or(pre2).test(s);
    }

    public static<R> R change(String s, Function<String,R> fun){
        R num = fun.apply(s);
        System.out.println(num);
        return num;
    }

    public static void change(String s,Function<String,Integer> fun1,Function<Integer,String> fun2){
        String  str = fun1.andThen(fun2).apply(s);
        System.out.println(str);
    }


    public static<T,U,V,R> R add(T t, U u, V v, TriFunction<T,U,V,R> triFunction, Consumer<T> consumer){

        R r = triFunction.apply(t,u,v);

        consumer.accept(t);

        return r;
    }

}
